/// 验证工具类 - 提供常用的数据验证方法
/// 原则：全面实用，不臃肿复杂
class Validator {
  /// 是否为空字符串
  static bool isEmpty(String? value) {
    return value == null || value.trim().isEmpty;
  }

  /// 是否不为空字符串
  static bool isNotEmpty(String? value) {
    return !isEmpty(value);
  }

  /// 是否为空值（null、空字符串、空列表、空Map）
  static bool isNull(dynamic value) {
    if (value == null) return true;
    if (value is String) return value.trim().isEmpty;
    if (value is List) return value.isEmpty;
    if (value is Map) return value.isEmpty;
    return false;
  }

  /// 是否不为空值
  static bool isNotNull(dynamic value) {
    return !isNull(value);
  }

  /// 邮箱格式验证
  static bool isEmail(String? email) {
    if (isEmpty(email)) return false;
    final emailRegex = RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$');
    return emailRegex.hasMatch(email!);
  }

  /// 邮箱域名验证（检查常见邮箱服务商）
  static bool isCommonEmail(String? email) {
    if (!isEmail(email)) return false;
    final commonDomains = ['gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com', 'qq.com', '163.com', '126.com', 'sina.com', 'sohu.com'];
    final domain = email!.split('@').last.toLowerCase();
    return commonDomains.contains(domain);
  }

  /// 中国大陆手机号验证
  static bool isChinesePhone(String? phone) {
    if (isEmpty(phone)) return false;
    final phoneRegex = RegExp(r'^1[3-9]\d{9}$');
    return phoneRegex.hasMatch(phone!);
  }

  /// 国际手机号验证（简化版）
  static bool isInternationalPhone(String? phone) {
    if (isEmpty(phone)) return false;
    // 国际手机号：+国家代码-手机号，如 +86-13800138000
    final phoneRegex = RegExp(r'^\+\d{1,4}-\d{6,14}$');
    return phoneRegex.hasMatch(phone!);
  }

  /// 手机号脱敏显示
  static String  maskPhone(String? phone) {
    if (isEmpty(phone) || phone!.length < 7) return phone ?? '';
    return '${phone.substring(0, 3)}****${phone.substring(phone.length - 4)}';
  }

  /// 中国大陆身份证验证
  static bool isChineseIdCard(String? idCard) {
    if (isEmpty(idCard)) return false;

    final idCardRegex = RegExp(r'^\d{17}[\dXx]$');
    if (!idCardRegex.hasMatch(idCard!)) return false;

    if (idCard.length != 18) return false;
    try {
      final year = int.parse(idCard.substring(6, 10));
      final month = int.parse(idCard.substring(10, 12));
      final day = int.parse(idCard.substring(12, 14));

      if (year < 1900 || year > DateTime.now().year) return false;
      if (month < 1 || month > 12) return false;
      if (day < 1 || day > 31) return false;
    } catch (e) {
      return false;
    }

    return true;
  }

  /// 身份证脱敏显示
  static String maskIdCard(String? idCard) {
    if (isEmpty(idCard) || idCard!.length < 10) return idCard ?? '';
    return '${idCard.substring(0, 6)}********${idCard.substring(idCard.length - 4)}';
  }

  /// 银行卡号验证（Luhn算法）
  static bool isBankCard(String? cardNumber) {
    if (isEmpty(cardNumber)) return false;
    final cleanNumber = cardNumber!.replaceAll(RegExp(r'\s'), '');
    if (!RegExp(r'^\d{13,19}$').hasMatch(cleanNumber)) return false;
    int sum = 0;
    bool isEven = false;
    for (int i = cleanNumber.length - 1; i >= 0; i--) {
      int digit = int.parse(cleanNumber[i]);
      if (isEven) {
        digit *= 2;
        if (digit > 9) digit -= 9;
      }
      sum += digit;
      isEven = !isEven;
    }

    return sum % 10 == 0;
  }

  /// 银行卡脱敏显示
  static String maskBankCard(String? cardNumber) {
    if (isEmpty(cardNumber) || cardNumber!.length < 8) return cardNumber ?? '';
    return '${cardNumber.substring(0, 4)} **** **** ${cardNumber.substring(cardNumber.length - 4)}';
  }

  /// URL格式验证
  static bool isUrl(String? url) {
    if (isEmpty(url)) return false;
    try {
      final uri = Uri.parse(url!);
      return uri.hasScheme && uri.hasAuthority;
    } catch (e) {
      return false;
    }
  }

  /// 是否是图片URL
  static bool isImageUrl(String? url) {
    if (!isUrl(url)) return false;
    final imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp'];
    return imageExtensions.any((ext) => url!.toLowerCase().contains(ext));
  }

  /// 是否是正整数
  static bool isPositiveInteger(String? value) {
    if (isEmpty(value)) return false;
    try {
      final number = int.parse(value!);
      return number > 0;
    } catch (e) {
      return false;
    }
  }

  /// 是否是正数（包含小数）
  static bool isPositiveNumber(String? value) {
    if (isEmpty(value)) return false;
    try {
      final number = double.parse(value!);
      return number > 0;
    } catch (e) {
      return false;
    }
  }

  /// 是否在指定范围内
  static bool isInRange(num value, num min, num max) {
    return value >= min && value <= max;
  }

  /// 是否是有效日期
  static bool isValidDate(String? dateStr, {String format = 'yyyy-MM-dd'}) {
    if (isEmpty(dateStr)) return false;
    try {
      // 简化验证，实际项目中可以使用 intl 包进行更严格的验证
      final parts = dateStr!.split('-');
      if (parts.length != 3) return false;

      final year = int.parse(parts[0]);
      final month = int.parse(parts[1]);
      final day = int.parse(parts[2]);

      if (year < 1900 || year > 2100) return false;
      if (month < 1 || month > 12) return false;
      if (day < 1 || day > 31) return false;

      return true;
    } catch (e) {
      return false;
    }
  }

  /// 是否是未来日期
  static bool isFutureDate(String? dateStr) {
    if (!isValidDate(dateStr)) return false;
    try {
      final date = DateTime.parse(dateStr!);
      return date.isAfter(DateTime.now());
    } catch (e) {
      return false;
    }
  }

  /// 是否是有效文件名
  static bool isValidFileName(String? fileName) {
    if (isEmpty(fileName)) return false;
    // 检查是否包含非法字符
    final invalidChars = RegExp(r'[<>:"/\\|?*]');
    return !invalidChars.hasMatch(fileName!);
  }

  /// 是否是图片文件
  static bool isImageFile(String? fileName) {
    if (isEmpty(fileName)) return false;
    final imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp'];
    return imageExtensions.any((ext) => fileName!.toLowerCase().endsWith(ext));
  }

  /// 是否是视频文件
  static bool isVideoFile(String? fileName) {
    if (isEmpty(fileName)) return false;
    final videoExtensions = ['.mp4', '.avi', '.mov', '.wmv', '.flv', '.mkv'];
    return videoExtensions.any((ext) => fileName!.toLowerCase().endsWith(ext));
  }

  /// 验证多个条件（全部满足）
  static bool validateAll(List<bool> conditions) {
    return conditions.every((condition) => condition);
  }

  /// 验证多个条件（满足任一）
  static bool validateAny(List<bool> conditions) {
    return conditions.any((condition) => condition);
  }
}
